﻿// Copyright (c) Inossem. All rights reserved.
// Licensed under the LGPL-3.0 license. See LICENSE file in the project root for full license information.
using DWF.Studio.ScriptEngine.Event;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DWF.Studio.ScriptEngine
{
    /// <summary>
    /// 脚本引擎基类
    /// </summary>
    internal abstract class ScriptEngineBase : IScriptEngine
    {
        public string Id
        {
            get;
            protected set;
        }

        public virtual Object ExcuteResult
        {
            get;
            protected set;
        }

        /// <summary>
        /// 执行终止事件
        /// </summary>
        public Action<ExecuteAbortedEventArgs> ExecuteAborted
        {
            get;
            set;
        }

        /// <summary>
        /// 执行完成事件
        /// </summary>
        public Action<ExecuteCompletedEventArgs> ExecuteCompleted
        {
            get;
            set;
        }

        /// <summary>
        /// 执行未处理异常
        /// </summary>
        public Action<ExecuteUnhandledExceptionEventArgs> ExecuteOnUnhandledException
        {
            get;
            set;
        }

        /// <summary>
        /// 执行输出
        /// </summary>
        public Action<char> ExcuteOutput
        {
            get;
            set;
        }

        /// <summary>
        /// 执行追踪
        /// </summary>
        public Action<ExecuteTrackEventArgs> ExecuteTrack
        {
            get;
            set;
        }

        public Action<DebugTrackEventArgs> DebugTrack
        {
            get;
            set;
        }

        public Action<HitBreakpointEventArgs> HitBreakpoint
        {
            get;
            set;
        }

        public Action<EventArgs> ExecuteStart
        {
            get;
            set;
        }

        public Action<EventArgs> ExecuteEnd
        {
            get;
            set;
        }

        /// <summary>
        /// 终止
        /// </summary>
        public abstract void Cancel();

        public abstract void DebugScript(string projectDirectory, string scriptPath);

        public abstract void DebugScript(string projectDirectory, string scriptPath, Dictionary<string, object> param);

        /// <summary>
        /// 执行脚本
        /// </summary>
        /// <param name="projectDirectory"></param>
        /// <param name="scriptPath"></param>
        public abstract void ExecuteScript(string projectDirectory, string scriptPath);

        /// <summary>
        /// 执行脚本
        /// </summary>
        /// <param name="projectDirectory"></param>
        /// <param name="scriptPath"></param>
        /// <param name="param"></param>
        public abstract void ExecuteScript(string projectDirectory, string scriptPath, Dictionary<string, object> param);

        /// <summary>
        /// 加载依赖程序集
        /// </summary>
        /// <param name="assemblyNames"></param>
        public virtual void LoadDepencyAssemblies(string[] assemblyNames)
        {
            if (assemblyNames != null && assemblyNames.Length > 0)
            {
                foreach (var name in assemblyNames)
                {
                    AppDomain.CurrentDomain.Load(name);
                }
            }
        }

        public abstract void DebugResume();

        public abstract void DebugStepInto();

        public abstract void DebugStepOut();

        public abstract void DebugStepOver();

        public abstract void CallFrameInfo();

        #region IDisposable Support
        private bool disposedValue = false; // 要检测冗余调用

        protected virtual void Dispose(bool disposing)
        {
            if (!disposedValue)
            {
                if (disposing)
                {
                    // TODO: 释放托管状态(托管对象)。
                    OnDisposing();
                }

                // TODO: 释放未托管的资源(未托管的对象)并在以下内容中替代终结器。
                // TODO: 将大型字段设置为 null。

                disposedValue = true;
            }
        }

        // TODO: 仅当以上 Dispose(bool disposing) 拥有用于释放未托管资源的代码时才替代终结器。
        // ~ScriptEngineBase()
        // {
        //   // 请勿更改此代码。将清理代码放入以上 Dispose(bool disposing) 中。
        //   Dispose(false);
        // }

        // 添加此代码以正确实现可处置模式。
        public void Dispose()
        {
            // 请勿更改此代码。将清理代码放入以上 Dispose(bool disposing) 中。
            Dispose(true);
            // TODO: 如果在以上内容中替代了终结器，则取消注释以下行。
            // GC.SuppressFinalize(this);
        }

        protected virtual void OnDisposing()
        {
        }
        #endregion
    }
}
